﻿import numpy as np
import scipy.io as scio

# import os

'''
Flashing        single  85x7794
Signal          single  85x7794x64
StimulusCode    single  85x7794
StimulusType    single  85x7794
TargetChar      char    1×85

    1   2   3   4   5   6                   0   1   2   3   4   5
7   A   B   C   D   E   F               6   A   B   C   D   E   F
8   G   H   I   J   K   L               7   G   H   I   J   K   L
9   M   N   O   P   Q   R      ->       8   M   N   O   P   Q   R
10  S   T   U   V   W   X               9   S   T   U   V   W   X
11  Y   Z   1   2   3   4               10  Y   Z   1   2   3   4
12  5   6   7   8   9   _               11  5   6   7   8   9   _
'''

Subject_A_path = r"E:\文件\Documents\Python\大创\DataSet\BCI_Comp_III_Wads_2004\Subject_A_Train.mat"

colAddRowNum = 12
colMulRowNum = 6 * 6
times = 85
totalDataNum = 7794
channels = 64
windows = 240
data: dict = scio.loadmat(Subject_A_path)
channel = 10  # 分析的通道

Flashing: np.float64 = data["Flashing"].astype(np.float64)
Signal: np.float64 = data["Signal"].astype(np.float64)
StimulusCode: np.float64 = data["StimulusCode"].astype(np.float64)
StimulusType: np.float64 = data["StimulusType"].astype(np.float64)
TargetChar = data["TargetChar"]

responses = np.zeros((colAddRowNum, 15, windows, channels))  # 15是每个信号的行和列出现15次
letter = np.zeros((colMulRowNum, windows, channels))
score = np.zeros((colMulRowNum))
Target = np.zeros((times, windows, channels))
NonTarget = np.zeros((times, windows, channels))
Prec = np.zeros(times, dtype='S')
ScreenLetter = ["A", "B", "C", "D", "E", "F",
                "G", "H", "I", "J", "K", "L",
                "M", "N", "O", "P", "Q", "R",
                "S", "T", "U", "V", "W", "X",
                "Y", "Z", "1", "2", "3", "4",
                "5", "6", "7", "8", "9", "_"]

# print(Flashing)
# print(Signal)
# print(StimulusType)
# print(StimulusCode)
# print(TargetChar)

# print(np.size(Signal,0))

# log=open("./log.txt",'w')

for epoch in range(0, np.size(Signal, 0)):
    rowcolcount = np.zeros(12)
    for n in range(1, np.size(Signal, 1)):
        if Flashing[epoch, n] == 0 and Flashing[epoch, n - 1] == 1:
            rowcol = int(StimulusCode[epoch, n - 1]) - 1
            # assert rowcol>=0 and rowcol<12     不报错
            responses[rowcol, int(rowcolcount[rowcol]), :, :] = Signal[epoch, n - 24:n + windows - 24, :]
            rowcolcount[rowcol] += 1
            # log.write(str(responses.shape))
            # log.write("\n")
    # 下面是matlab中简单的预测器
    m = 0
    avgresp = np.mean(responses, axis=1)
    # print(avgresp.shape)
    # avgresp=avgresp.reshape((colAddRowNum,windows,channels))#已经是(colAddRowNum,windows,channels)大小
    for row in range(6, 12):
        for col in range(0, 6):
            letter[m, :, :] = (avgresp[row, :, :] + avgresp[col, :, :]) / 2
            score[m] = np.mean(letter[m, 54 - 1:124, channel]) - np.mean(letter[m, 134 - 1:174, channel])  # 一维应该无关轴
            m += 1
    # print(score)
    maxVal = np.max(score)
    maxIdx = np.argmax(score)
    # print(maxVal)
    # print(maxIdx)
    Prec[epoch] = ScreenLetter[maxIdx]
    label = np.unique(np.multiply(StimulusCode[epoch, :], StimulusType[epoch, :]))
    targetLabel = (6 * (int(label[2]) - 7)) + int(label[1]);
    Target[epoch, :, :] = 0.5 * (avgresp[int(label[1]) - 1, :, :] + avgresp[int(label[2]) - 1, :, :])
    NonTarget[epoch, :, :] = np.mean(avgresp, axis=0) - (1 / 6) * Target[epoch, :, :]

k = 0
for i in range(0, np.size(Signal, 0)):
    if Prec[i].decode('utf-8') == TargetChar[0][i]:
        k += 1

# print(Prec)
correct = (k / np.size(Signal, 0)) * 100;
print("correct is {0}%".format(correct))
# print(responses)
# log.close()
